﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Security;
using TeamsPortal.Localization;
using TeamsPortal.Security;
using TeamsPortal.Web.Controllers.Filters;

namespace TeamsPortal.Web.Api
{
    public class RolesController : ApiController
    {
        private readonly IRoleService _roleService;
        private readonly ILocalizer _localizer;
        private readonly IMembershipService _membershipService;

        public RolesController(IRoleService roleService, IMembershipService membershipService, ILocalizer localizer)
        {
            _roleService = roleService;
            _membershipService = membershipService;
            _localizer = localizer;
        }

        [RequireAuthorization(UserRole.Admin)]
        public IEnumerable<object> GetAll()
        {
            string[] roles = _roleService.GetAll();
            var result = (from roleName in roles select new { Name = roleName }).ToArray();

            return result;
        }

        [RequireAuthorization(UserRole.Admin)]
        public HttpResponseMessage GetUsersInRole(string roleName)
        {
            try
            {
                string[] users = _roleService.GetUsersInRole(roleName);
                var result = (from userName in users select new { Name = userName }).ToArray();

                return Request.CreateResponse<IEnumerable<object>>(HttpStatusCode.OK, result);
            }
            catch (Exception ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="roleName">exception role name</param>
        /// <returns></returns>
        [RequireAuthorization(UserRole.Admin)]
        public HttpResponseMessage GetAllUsers(string roleName)
        {
            try
            {
                var users = _membershipService.GetAllUsers();
                var result = (from u in users.Cast<MembershipUser>() select new { Name = u.UserName });
                if (!string.IsNullOrEmpty(roleName))
                {
                    result = result.Where(u=>!_roleService.IsUserInRole(u.Name, roleName));
                }

                return Request.CreateResponse<IEnumerable<object>>(HttpStatusCode.OK, result.ToArray());
            }
            catch (Exception ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
        }

        /// <summary>
        /// Creates a new role
        /// </summary>
        /// <param name="roleName"></param>
        /// <returns></returns>
        [RequireAuthorization(UserRole.Admin)]
        public HttpResponseMessage Insert([FromBody]string roleName)
        {
            if (string.IsNullOrEmpty(roleName))
                return Request.CreateResponse(HttpStatusCode.BadRequest, _localizer.Get("Role name is empty."));
            //todo: check admin role

            try
            {
                _roleService.Create(roleName);
            }
            catch (Exception ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message);
            }

            return Request.CreateResponse(HttpStatusCode.Created);
        }

        [RequireAuthorization(UserRole.Admin)]
        public HttpResponseMessage Delete([FromBody]string roleName)
        {
            //todo: validate roleName
            //todo: check admin role
            try
            {
                bool isRemoved = _roleService.Delete(roleName);
                //todo: if roleName doesn't exist isRemoved will be false

                return Request.CreateResponse(HttpStatusCode.OK);
            }
            catch (Exception ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
        }

        [RequireAuthorization(UserRole.Admin)]
        public HttpResponseMessage AddUserToRole(UserRoleModel model)
        {
            try
            {
                _roleService.AddUserToRole(model.UserName, model.RoleName);

                return Request.CreateResponse(HttpStatusCode.OK);
            }
            catch (Exception ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
        }

        [RequireAuthorization(UserRole.Admin)]
        public HttpResponseMessage RemoveUserFromRole(UserRoleModel model)
        {
            try
            {
                _roleService.RemoveUserFromRole(model.UserName, model.RoleName);

                return Request.CreateResponse(HttpStatusCode.OK);
            }
            catch (Exception ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
        }
    }

    public class UserRoleModel
    {
        public string UserName { get; set; }
        public string RoleName { get; set; }
    }
}